"""
HTTP服务器端工具，支持根据请求类型返回内容，可自定义条件和延迟等
"""

import json
import time
from http.server import HTTPServer, BaseHTTPRequestHandler
from typing import Dict, Any, Callable, Optional, Union


class HTTPRequestHandler(BaseHTTPRequestHandler):
    """
    HTTP请求处理器
    """

    def __init__(self, request, client_address, server):
        """
        初始化请求处理器
        """
        # 存储服务器配置
        self.response_rules = server.response_rules
        self.delay_rules = server.delay_rules
        self.custom_conditions = server.custom_conditions
        self.response_data = server.response_data
        
        super().__init__(request, client_address, server)

    def log_message(self, format, *args):
        """
        重写日志方法，保持简洁
        """
        pass

    def _send_response(self, status_code: int, data: Dict[str, Any], 
                      headers: Optional[Dict[str, str]] = None):
        """
        发送响应

        :param status_code: HTTP状态码
        :param data: 响应数据
        :param headers: 响应头
        """
        # 转换数据为JSON格式
        response_data = json.dumps(data, ensure_ascii=False).encode('utf-8')
        
        # 发送响应
        self.send_response(status_code)
        
        # 设置默认头
        self.send_header('Content-Type', 'application/json; charset=utf-8')
        self.send_header('Content-Length', str(len(response_data)))
        
        # 添加自定义头
        if headers:
            for key, value in headers.items():
                self.send_header(key, value)
        
        self.end_headers()
        self.wfile.write(response_data)

    def _check_conditions(self, request_data: Dict[str, Any]) -> bool:
        """
        检查自定义条件

        :param request_data: 请求数据
        :return: 是否满足条件
        """
        if not self.custom_conditions:
            return True
            
        for condition in self.custom_conditions:
            if not condition(request_data):
                return False
        return True

    def _get_delay(self, request_type: str) -> float:
        """
        获取延迟时间

        :param request_type: 请求类型
        :return: 延迟时间（秒）
        """
        return self.delay_rules.get(request_type, 0)

    def _get_response_data(self, request_type: str, request_data: Dict[str, Any]) -> Dict[str, Any]:
        """
        获取响应数据

        :param request_type: 请求类型
        :param request_data: 请求数据
        :return: 响应数据
        """
        # 根据请求类型获取响应规则
        rule = self.response_rules.get(request_type)
        if rule:
            return rule(request_data)
        
        # 根据字段内容获取响应数据
        for field, responses in self.response_data.items():
            if field in request_data:
                field_value = request_data[field]
                if field_value in responses:
                    return responses[field_value]
        
        # 返回默认数据
        return {"message": "Default response"}

    def do_GET(self):
        """
        处理GET请求
        """
        # 应用延迟
        delay = self._get_delay('GET')
        if delay > 0:
            time.sleep(delay)
        
        # 构造请求数据
        request_data = {
            "method": "GET",
            "path": self.path,
            "headers": dict(self.headers)
        }
        
        # 检查条件
        if not self._check_conditions(request_data):
            self._send_response(403, {"error": "Condition not met"})
            return
        
        # 获取响应数据
        response_data = self._get_response_data('GET', request_data)
        
        # 发送响应
        self._send_response(200, response_data)

    def do_POST(self):
        """
        处理POST请求
        """
        # 获取请求内容长度
        content_length = int(self.headers.get('Content-Length', 0))
        
        # 读取请求数据
        post_data = self.rfile.read(content_length)
        
        # 解析JSON数据
        try:
            request_data = json.loads(post_data.decode('utf-8')) if post_data else {}
        except json.JSONDecodeError:
            request_data = {}
        
        # 添加请求信息
        request_data.update({
            "method": "POST",
            "path": self.path,
            "headers": dict(self.headers)
        })
        
        # 应用延迟
        delay = self._get_delay('POST')
        if delay > 0:
            time.sleep(delay)
        
        # 检查条件
        if not self._check_conditions(request_data):
            self._send_response(403, {"error": "Condition not met"})
            return
        
        # 获取响应数据
        response_data = self._get_response_data('POST', request_data)
        
        # 发送响应
        self._send_response(200, response_data)

    def do_PUT(self):
        """
        处理PUT请求
        """
        # 获取请求内容长度
        content_length = int(self.headers.get('Content-Length', 0))
        
        # 读取请求数据
        put_data = self.rfile.read(content_length)
        
        # 解析JSON数据
        try:
            request_data = json.loads(put_data.decode('utf-8')) if put_data else {}
        except json.JSONDecodeError:
            request_data = {}
        
        # 添加请求信息
        request_data.update({
            "method": "PUT",
            "path": self.path,
            "headers": dict(self.headers)
        })
        
        # 应用延迟
        delay = self._get_delay('PUT')
        if delay > 0:
            time.sleep(delay)
        
        # 检查条件
        if not self._check_conditions(request_data):
            self._send_response(403, {"error": "Condition not met"})
            return
        
        # 获取响应数据
        response_data = self._get_response_data('PUT', request_data)
        
        # 发送响应
        self._send_response(200, response_data)

    def do_DELETE(self):
        """
        处理DELETE请求
        """
        # 构造请求数据
        request_data = {
            "method": "DELETE",
            "path": self.path,
            "headers": dict(self.headers)
        }
        
        # 应用延迟
        delay = self._get_delay('DELETE')
        if delay > 0:
            time.sleep(delay)
        
        # 检查条件
        if not self._check_conditions(request_data):
            self._send_response(403, {"error": "Condition not met"})
            return
        
        # 获取响应数据
        response_data = self._get_response_data('DELETE', request_data)
        
        # 发送响应
        self._send_response(200, response_data)

    def do_PATCH(self):
        """
        处理PATCH请求
        """
        # 获取请求内容长度
        content_length = int(self.headers.get('Content-Length', 0))
        
        # 读取请求数据
        patch_data = self.rfile.read(content_length)
        
        # 解析JSON数据
        try:
            request_data = json.loads(patch_data.decode('utf-8')) if patch_data else {}
        except json.JSONDecodeError:
            request_data = {}
        
        # 添加请求信息
        request_data.update({
            "method": "PATCH",
            "path": self.path,
            "headers": dict(self.headers)
        })
        
        # 应用延迟
        delay = self._get_delay('PATCH')
        if delay > 0:
            time.sleep(delay)
        
        # 检查条件
        if not self._check_conditions(request_data):
            self._send_response(403, {"error": "Condition not met"})
            return
        
        # 获取响应数据
        response_data = self._get_response_data('PATCH', request_data)
        
        # 发送响应
        self._send_response(200, response_data)


class HTTPServerTool:
    """
    HTTP服务器工具类
    """

    def __init__(self, host: str = 'localhost', port: int = 8000):
        """
        初始化HTTP服务器

        :param host: 服务器主机名
        :param port: 服务器端口
        """
        self.host = host
        self.port = port
        self.server = None
        
        # 响应规则：根据请求类型定义响应函数
        self.response_rules: Dict[str, Callable] = {}
        
        # 延迟规则：根据请求类型定义延迟时间
        self.delay_rules: Dict[str, float] = {}
        
        # 自定义条件：函数列表，用于检查请求是否满足特定条件
        self.custom_conditions: list = []
        
        # 响应数据：根据字段内容返回特定数据
        self.response_data: Dict[str, Dict[str, Dict[str, Any]]] = {}

    def set_response_rule(self, method: str, handler: Callable[[Dict[str, Any]], Dict[str, Any]]) -> None:
        """
        设置响应规则

        :param method: HTTP方法（GET、POST等）
        :param handler: 处理函数，接收请求数据，返回响应数据
        """
        self.response_rules[method] = handler

    def set_delay(self, method: str, delay: float) -> None:
        """
        设置延迟时间

        :param method: HTTP方法
        :param delay: 延迟时间（秒）
        """
        self.delay_rules[method] = delay

    def add_condition(self, condition: Callable[[Dict[str, Any]], bool]) -> None:
        """
        添加自定义条件

        :param condition: 条件函数，接收请求数据，返回布尔值
        """
        self.custom_conditions.append(condition)

    def set_field_response(self, field: str, value: str, response: Dict[str, Any]) -> None:
        """
        设置字段响应

        :param field: 字段名
        :param value: 字段值
        :param response: 响应数据
        """
        if field not in self.response_data:
            self.response_data[field] = {}
        self.response_data[field][value] = response

    def start(self) -> None:
        """
        启动服务器
        """
        # 创建自定义处理器类，传递配置
        class CustomHTTPRequestHandler(HTTPRequestHandler):
            def __init__(self, request, client_address, server):
                super().__init__(request, client_address, server)
        
        # 创建服务器
        self.server = HTTPServer((self.host, self.port), CustomHTTPRequestHandler)
        
        # 将配置传递给服务器
        self.server.response_rules = self.response_rules
        self.server.delay_rules = self.delay_rules
        self.server.custom_conditions = self.custom_conditions
        self.server.response_data = self.response_data
        
        print(f"HTTP服务器启动在 http://{self.host}:{self.port}")
        print("按 Ctrl+C 停止服务器")
        
        try:
            self.server.serve_forever()
        except KeyboardInterrupt:
            print("\n服务器已停止")
            self.server.server_close()

    def stop(self) -> None:
        """
        停止服务器
        """
        if self.server:
            self.server.shutdown()
            self.server.server_close()